package com.sky.loveshop.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sky.loveshop.api.Apis;
import com.sky.loveshop.api.MeiTuanOrderRequest;
import com.sky.loveshop.entity.*;
import com.sky.loveshop.entity.exception.BizException;
import com.sky.loveshop.entity.exception.BizExceptionEnum;
import com.sky.loveshop.entity.meiTuan.*;
import com.sky.loveshop.entity.qo.MtOrderInfoQO;
import com.sky.loveshop.entity.qo.StockParam;
import com.sky.loveshop.entity.vo.MeiTuanOrderVO;
import com.sky.loveshop.entity.vo.ProductVO;
import com.sky.loveshop.entity.vo.SkuVO;
import com.sky.loveshop.mapper.MeiTuanOrderDetailMapper;
import com.sky.loveshop.mapper.MeiTuanOrderMapper;
import com.sky.loveshop.service.*;
import com.sky.loveshop.utils.QiYeWeChatSendMsgUtil;
import com.sky.loveshop.utils.SignUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.io.File;
import java.time.Instant;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.sky.loveshop.entity.common.SysConstants.NEW_ORDER_QI_YE_WECHAT_GROUP_01_KEY;

/**
 * @author xcy
 * @version V1.0
 * @description
 * @date 2024/9/2 23:37
 */
@Slf4j
@Service
public class MtServiceImpl implements MtService {

    @Autowired
    private MeiTuanOrderMapper meiTuanOrderMapper;
    @Autowired
    private MeiTuanOrderDetailMapper meiTuanOrderDetailMapper;
    @Autowired
    private ProductService productService;
    @Autowired
    private SkuService skuService;
    @Autowired
    private ShopService shopService;
    @Autowired
    private DeliverRecordService deliverRecordsService;
    @Autowired
    private DeliverRecordTimelineService deliverRecordTimelineService;
    @Autowired
    private PrivateOrderInfoService privateOrderInfoService;
    @Autowired
    private QiYeWeChatSendMsgUtil qiYeWeChatSendMsgUtil;

    @Value("${waiSongBang.appKey}")
    private String waiSongBangAppKey;
    @Value("${waiSongBang.appSecret}")
    private String waiSongBangAppSecret;

    @Override
    public MtStoreCreateResponse createStore() {

        // 先获取签名
        long second = Instant.now().getEpochSecond();
        Map<String, Object> params = new HashMap<>();
        params.put("app_key", waiSongBangAppKey);
        params.put("timestamp", second);
        params.put("version", "1.0");
        params.put("name", "光明店4");
        params.put("owner_name", "松");
        params.put("tel", "18617151926");
        params.put("city", "深圳市");
        params.put("area", "龙华区");
        params.put("address", "光明街道");
        params.put("lng", 112.981915f);
        params.put("lat", 28.168416f);
        params.put("open_start", "00:00:00");
        params.put("open_end", "23:59:59");

        String sign = SignUtils.generateSignature(params, waiSongBangAppSecret);

        MeiTuanOrderRequest.CreateStoreRequest createStoreRequest = new MeiTuanOrderRequest.CreateStoreRequest();
        createStoreRequest.setApp_key(waiSongBangAppKey);
        createStoreRequest.setTimestamp(second);
        createStoreRequest.setVersion("1.0");
        createStoreRequest.setSign(sign);
        createStoreRequest.setName("光明店4");
        createStoreRequest.setOwner_name("松");
        createStoreRequest.setTel("18617151926");
        createStoreRequest.setCity("深圳市");
        createStoreRequest.setArea("龙华区");
        createStoreRequest.setAddress("光明街道");
        createStoreRequest.setLng(112.981915f);
        createStoreRequest.setLat(28.168416f);
        createStoreRequest.setOpen_start("00:00:00");
        createStoreRequest.setOpen_end("23:59:59");

        MtStoreCreateResponse mtOrderResponse = null;

        try {
            log.info("createStore Request param = {}", JSONUtil.toJsonStr(createStoreRequest));
            mtOrderResponse = Apis.WAI_SONG_BANG_API.createStore(createStoreRequest);
            log.info("createStore Response 创建商店 name=【{}】 响应结果=【{}】", createStoreRequest.getName(), JSONUtil.toJsonStr(mtOrderResponse));
        } catch (Exception e) {
            log.error("createStore Error 创建商店过程报错 name=【{}】", createStoreRequest.getName(), e);
            e.printStackTrace();
        }

        if (null != mtOrderResponse && mtOrderResponse.isSuccess()) {
            log.info("createStore Success 创建商店 name=【{}】", createStoreRequest.getName());
        }
        return mtOrderResponse;
    }

    @Override
    public MtOrderCreateResponse createMtOrder(MeiTuanOrderRequest.CreateOrderRequest request) {

        // 先获取签名
        long second = Instant.now().getEpochSecond();
        Map<String, Object> params = new HashMap<>();
        params.put("app_key", waiSongBangAppKey);
        params.put("timestamp", second);
        params.put("version", "1.0");
        params.put("store_id", request.getStore_id());
        params.put("receiver_name", request.getReceiver_name());
        params.put("receiver_address", request.getReceiver_address());
        params.put("receiver_phone", request.getReceiver_phone());
        params.put("receiver_lng", request.getReceiver_lng());
        params.put("receiver_lat", request.getReceiver_lat());
        params.put("platform_order_id", request.getPlatform_order_id());
        params.put("platform_day_id", request.getPlatform_day_id());
        params.put("order_weight", request.getOrder_weight());
        params.put("order_amount", request.getOrder_amount());
        params.put("remark", request.getRemark());

        // 组装json字符串的商品信息
        List<MeiTuanOrderRequest.orderItems> orderItemList = request.getOrder_items();
        /*
        List<MeiTuanOrderRequest.orderItems> orderItemList = new ArrayList<>();
        MeiTuanOrderRequest.orderItems item = new MeiTuanOrderRequest.orderItems();
        item.setNum(1);
        item.setSku_id(1);
        orderItemList.add(item);
        ObjectMapper objectMapper = new ObjectMapper();
        String itemsString = "";
        try {
            itemsString = objectMapper.writeValueAsString(orderItemList);
            System.out.println("【看下list转json字符串】"+itemsString);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        //params.put("order_items", itemsString);
         */

        // list值时直接使用"Array"来替代所有结果
        // params.put("order_items", "Array");
        // 只关注配送时，不要传这个参数


        String sign = SignUtils.generateSignature(params, waiSongBangAppSecret);
        //log.info("createMtOrderSign={} second={}", sign, second);

        MeiTuanOrderRequest.CreateOrderRequest createOrderRequest = new MeiTuanOrderRequest.CreateOrderRequest();
        createOrderRequest.setApp_key(waiSongBangAppKey);
        createOrderRequest.setTimestamp(second);
        createOrderRequest.setVersion("1.0");
        createOrderRequest.setSign(sign);
        createOrderRequest.setStore_id(request.getStore_id());
        createOrderRequest.setReceiver_name(request.getReceiver_name());
        createOrderRequest.setReceiver_address(request.getReceiver_address());
        createOrderRequest.setReceiver_phone(request.getReceiver_phone());
        createOrderRequest.setReceiver_lng(request.getReceiver_lng());
        createOrderRequest.setReceiver_lat(request.getReceiver_lat());
        createOrderRequest.setPlatform_order_id(request.getPlatform_order_id());
        createOrderRequest.setPlatform_day_id(request.getPlatform_day_id());
        createOrderRequest.setOrder_weight(request.getOrder_weight());
        createOrderRequest.setOrder_amount(request.getOrder_amount());
        createOrderRequest.setOrder_items(orderItemList);
        createOrderRequest.setRemark(request.getRemark());

        MtOrderCreateResponse mtOrderResponse = null;

        try {
            log.info("createMtOrder param = {}", JSONUtil.toJsonStr(createOrderRequest));
            mtOrderResponse = Apis.WAI_SONG_BANG_API.createOrder(createOrderRequest);
            log.info("createMtOrder Response platformOrderId=【{}】 下单响应结果=【{}】", createOrderRequest.getPlatform_order_id(), JSONUtil.toJsonStr(mtOrderResponse));
            //createMtOrder Response platformOrderId=【xyzg100008】 下单响应结果=【{"msg":"成功","code":0,"data":{"orderId":234764001}}】
        } catch (Exception e) {
            log.error("createMtOrder Error 下单过程报错 platformOrderId=【{}】", createOrderRequest.getPlatform_order_id(), e);
            e.printStackTrace();
        }
        if (null != mtOrderResponse && mtOrderResponse.isSuccess()) {
            log.info("createMtOrder Success 下单成功 platformOrderId=【{}】", createOrderRequest.getPlatform_order_id());
        }
        return mtOrderResponse;
    }

    @Override
    public MtOrderPullResponse getMtOrderInfoListByStoreId(Integer storeId, Integer deliverStatus) {
        // 先获取签名
        long second = Instant.now().getEpochSecond();
        Map<String, Object> params = new HashMap<>();
        params.put("app_key", waiSongBangAppKey);
        params.put("deliver_status", deliverStatus);
        // 光明店铺id - 168248
        params.put("store_id", storeId);
        params.put("timestamp", second);
        params.put("version", "1.0");
        //params.put("start_date", "2024-11-06");
        //params.put("end_date", "2024-11-06");
        String sign = SignUtils.generateSignature(params, waiSongBangAppSecret);

        MeiTuanOrderRequest.PullOrderRequest pullOrderRequest = new MeiTuanOrderRequest.PullOrderRequest();
        pullOrderRequest.setApp_key(waiSongBangAppKey);
        // 订单配送状态，1：待接单/转单，2：待取货/已接单，3：配送中，4：配送完成，5：配送取消
        // 运单状态：创建=0,已接单=1,已取货=2,在途=3,完成=4,已取消=5
        pullOrderRequest.setDeliver_status(deliverStatus);
        pullOrderRequest.setStore_id(storeId);
        pullOrderRequest.setTimestamp(second);
        pullOrderRequest.setVersion("1.0");
        //pullOrderRequest.setStart_time("2024-11-06");
        //pullOrderRequest.setEnd_time("2024-11-06");
        pullOrderRequest.setSign(sign);
        MtOrderPullResponse mtOrderPullResponse = null;
        try {
            log.info("pullOrderList1 request 从外送帮拉取美团订单请求信息 {}", JSONUtil.toJsonStr(pullOrderRequest));
            mtOrderPullResponse = Apis.WAI_SONG_BANG_API.pullOrderList(pullOrderRequest);
            log.info("pullOrderList1 response 从外送帮拉取美团订单响应结果 {}", JSONUtil.toJsonStr(mtOrderPullResponse));
        } catch (Exception e) {
            log.error("pullOrderList1 Error 从外送帮拉取美团订单过程报错", e);
            e.printStackTrace();
        }
        return mtOrderPullResponse;
    }

    @Override
    @Transactional
    public void getMtOrderAndInsert(Integer storeId) {

        // 获取美团的订单数据并存入到数据库中
        // 直接解析json数据模拟获取到的数据
        //MtOrderResponse mtOrderResponse = parseJson();

        // 先获取签名
        long second = Instant.now().getEpochSecond();
        Map<String, Object> params = new HashMap<>();
        params.put("app_key", waiSongBangAppKey);
        params.put("deliver_status", 2);
        // 光明店铺id - 168248
        params.put("store_id", storeId);
        params.put("timestamp", second);
        params.put("version", "1.0");
        //params.put("start_date", "2024-11-06");
        //params.put("end_date", "2024-11-06");
        String sign = SignUtils.generateSignature(params, waiSongBangAppSecret);

        MeiTuanOrderRequest.PullOrderRequest pullOrderRequest = new MeiTuanOrderRequest.PullOrderRequest();
        pullOrderRequest.setApp_key(waiSongBangAppKey);
        // 订单配送状态，1：待接单/转单，2：待取货/已接单，3：配送中，4：配送完成，5：配送取消
        // 运单状态：创建=0,已接单=1,已取货=2,在途=3,完成=4,已取消=5
        pullOrderRequest.setDeliver_status(2);
        pullOrderRequest.setStore_id(storeId);
        pullOrderRequest.setTimestamp(second);
        pullOrderRequest.setVersion("1.0");
        //pullOrderRequest.setStart_time("2024-11-06");
        //pullOrderRequest.setEnd_time("2024-11-06");
        pullOrderRequest.setSign(sign);
        MtOrderPullResponse mtOrderPullResponse = null;
        try {
            //mtOrderPullResponse = parsePullOrderResponse2Json();
            log.info("pullOrderList request 从外送帮拉取美团订单请求信息 {}", JSONUtil.toJsonStr(pullOrderRequest));
            mtOrderPullResponse = Apis.WAI_SONG_BANG_API.pullOrderList(pullOrderRequest);
            log.info("pullOrderList response 从外送帮拉取美团订单响应结果 {}", JSONUtil.toJsonStr(mtOrderPullResponse));
        } catch (Exception e) {
            log.error("pullOrderList Error 从外送帮拉取美团订单过程报错", e);
            e.printStackTrace();
        }

        if (null == mtOrderPullResponse || mtOrderPullResponse.getCode() != 0) {
            return;
        }


        // 先组装主表数据
        // 再组装详情表数据
        // 比对主表的订单是否已经存在库中，已经存在的则不进行添加
        // 不存在的则先添加主表，再添加详情表
        MtOrderPullResponse.DataDTO data = mtOrderPullResponse.getData();
        if (data == null || CollectionUtil.isEmpty(data.getLists())) {
            return;
        }
        // 如果这一个门店有很多待取货订单，必须分页处理，但是此接口拉取美团订单默认一页是30条，最大支持200条。先用默认的30条就够了，不够后面再调整大点。
        List<MtOrderPullResponse.OrderDTO> mtOrderLists = data.getLists();
        log.info("pullOrderList total 从外送帮拉取美团符合条件的订单数量={}", data.getTotal());
        for (MtOrderPullResponse.OrderDTO m : mtOrderLists) {
            Example example = new Example(MeiTuanOrder.class);
            example.createCriteria().andEqualTo("orderId", m.getId());
            MeiTuanOrder meiTuanOrder = meiTuanOrderMapper.selectOneByExample(example);
            if (null != meiTuanOrder) {
                log.info("pullOrderList noRepeatPull 已经拉取过了 {} 不再重复添加", m.getId());
                continue;
            }

            MeiTuanOrder o = manageMeiTuanOrder(m);

            meiTuanOrderMapper.insert(o);

            Shop shop = shopService.getShopByStoreId(m.getStoreId());
            // 发送新订单通知消息到企业微信群
            String msg = assembleNewOrderMsg(shop.getName(), shop.getAddress(), m.getPlatformOrderId(), m.getPlatformDayId(), DateUtil.formatDateTime(new Date()));
            qiYeWeChatSendMsgUtil.sendMarkdownMsg(NEW_ORDER_QI_YE_WECHAT_GROUP_01_KEY, msg);

            // platformOrderId不为xyzg开头
            if (!o.getPlatformOrderId().startsWith("xyzg")) {
                List<MtOrderPullResponse.OrderItemDTO> mtOrderItemList = m.getGoodsList();
                if (CollectionUtil.isNotEmpty(mtOrderItemList)) {
                    for (MtOrderPullResponse.OrderItemDTO d : mtOrderItemList) {
                        MeiTuanOrderDetail detail = manageMeiTuanOrderDetail(d);
                        detail.setMtOrderId(o.getId());
                        detail.setStoreId(o.getStoreId());
                        detail.setShopId(o.getShopId());
                        meiTuanOrderDetailMapper.insert(detail);
                    }
                }
            } else {
                // platformOrderId为xyzg开头，即私域订单

                // 私域订单详情这里存也可以，也可以在订单详情查询时组装私域订单详情到核销app页面

            }


            // 再订单主单和订单详情都新增插入成功后再获取此订单对应的配送日志信息
            pullDeliverRecordsAndInsert(m.getPlatformOrderId());
        }
    }

    /**
     * 组装新订单通知消息
     *
     * @param shopName 商店名称
     * @param address  商店地址
     * @param platformOrderId  平台订单id
     * @param platformDayId  平台订单序号
     * @param createTime 开门时间
     */
    private String assembleNewOrderMsg(String shopName, String address, String platformOrderId, Integer platformDayId, String createTime) {
        StringBuilder msg = new StringBuilder();
        msg.append("#### 新订单通知\n");
        msg.append(">商店名称：").append(shopName).append("\n");
        msg.append(">商店地址：").append(address).append("\n");
        msg.append(">订单序号：").append(platformDayId).append("\n");
        msg.append(">订单编号：").append(platformOrderId).append("\n");
        msg.append(">订单时间：").append(createTime).append("\n");
        return msg.toString();
    }

    /**
     * 拉取配送日志
     * 这里报错不要影响到订单的插入
     *
     * @param platformOrderId 美团订单id
     */
    private void pullDeliverRecordsAndInsert(String platformOrderId) {
        MtOrderPullDeliverRecordsResponse recordsResponse;
        try {
            // 先获取签名
            long second = Instant.now().getEpochSecond();
            Map<String, Object> params = new HashMap<>();
            params.put("app_key", waiSongBangAppKey);
            params.put("timestamp", second);
            params.put("version", "1.0");
            String sign = SignUtils.generateSignature(params, waiSongBangAppSecret);

            //MeiTuanOrder.PullOrderRequest pullOrderRequest = new MeiTuanOrder.PullOrderRequest();
            //pullOrderRequest.setApp_key(waiSongBangAppKey);
            //pullOrderRequest.setTimestamp(second);
            //pullOrderRequest.setVersion("1.0");
            //pullOrderRequest.setSign(sign);
            MeiTuanOrderRequest.PullDeliverRecordsRequest request = new MeiTuanOrderRequest.PullDeliverRecordsRequest();
            request.setApp_key(waiSongBangAppKey);
            request.setTimestamp(second);
            request.setVersion("1.0");
            request.setSign(sign);
            log.info("pullDeliverRecordsAndInsert 拉取订单对应的配送日志请求 platformOrderId=【{}】 Request=【{}】", platformOrderId, JSONUtil.toJsonStr(request));
            //recordsResponse = parsePullDeliverRecordResponse2Json();
            recordsResponse = Apis.WAI_SONG_BANG_API.pullDeliverRecords(platformOrderId, request);
            log.info("pullDeliverRecordsAndInsert Response 拉取订单对应的配送日志响应 platformOrderId=【{}】, response=【{}】", platformOrderId, JSONUtil.toJsonStr(recordsResponse));

            String driverPhone = null;
            if (null != recordsResponse && recordsResponse.isSuccess()) {
                List<MtOrderPullDeliverRecordsResponse.DataDTO> dataList = recordsResponse.getData();
                if (CollectionUtil.isEmpty(dataList)) {
                    log.info("pullDeliverRecordsAndInsert 拉取订单对应的配送日志为空 platformOrderId=【{}】", platformOrderId);
                    return;
                }

                // 注意：这里观察返回结果发现配送日志是数组包数组的，最外层的只需要拿去state=1已接单的这条记录，其他状态不用获取，只有已接单状态才有骑手姓名手机号
                for (MtOrderPullDeliverRecordsResponse.DataDTO d : dataList) {
                    // 运单状态：待接单＝1,待取货＝2,配送中＝3,已完成＝4,已取消＝5(这个是文档上来的，压根跟实际对不上，以下方注释为准)
                    // 运单状态：创建=0,已接单=1,已取货=2,在途=3,完成=4,已取消=5
                    if (1 == d.getState() || 2 == d.getState() || 3 == d.getState() || 4 == d.getState()) {
                        // 获取到骑手手机号 用后4位写入到美团主订单表的尾号
                        driverPhone = d.getDriverPhone();
                        DeliverRecord deliverRecord = manageDeliverRecord(platformOrderId, d);
                        deliverRecordsService.insertOne(deliverRecord);

                        List<MtOrderPullDeliverRecordsResponse.DataDTO.TimelineDTO> timelineList = d.getTimeline();
                        if (CollectionUtil.isNotEmpty(timelineList)) {
                            for (MtOrderPullDeliverRecordsResponse.DataDTO.TimelineDTO t : timelineList) {
                                DeliverRecordTimeline timeline = manageDeliverRecordTimeline(platformOrderId, t);
                                timeline.setDeliverRecordId(deliverRecord.getId());
                                deliverRecordTimelineService.insertOne(timeline);
                            }
                        }
                    }
                }

                // 将骑手尾号后四位更新到美团主订单表，用来骑手通过取货码开门
                meiTuanOrderMapper.updatePhoneCodeByPlatformOrderId(platformOrderId, driverPhone.substring(driverPhone.length() - 4));
            }
        } catch (Exception e) {
            log.error("pullDeliverRecordsAndInsert Error {}", platformOrderId, e);
            e.printStackTrace();
        }
    }

    /**
     * 拉取配送日志
     *
     * @param platformOrderId
     */
    public MtOrderPullDeliverRecordsResponse pullDeliverRecordsByPlatformOrderId(String platformOrderId) {
        MtOrderPullDeliverRecordsResponse recordsResponse;
        try {
            // 先获取签名
            long second = Instant.now().getEpochSecond();
            Map<String, Object> params = new HashMap<>();
            params.put("app_key", waiSongBangAppKey);
            params.put("timestamp", second);
            params.put("version", "1.0");
            String sign = SignUtils.generateSignature(params, waiSongBangAppSecret);

            MeiTuanOrderRequest.PullDeliverRecordsRequest request = new MeiTuanOrderRequest.PullDeliverRecordsRequest();
            request.setApp_key(waiSongBangAppKey);
            request.setTimestamp(second);
            request.setVersion("1.0");
            request.setSign(sign);
            log.info("pullDeliverRecordsAndInsert 拉取订单对应的配送日志请求 platformOrderId=【{}】 Request=【{}】", platformOrderId, JSONUtil.toJsonStr(request));
            recordsResponse = Apis.WAI_SONG_BANG_API.pullDeliverRecords(platformOrderId, request);
            log.info("pullDeliverRecordsAndInsert Response 拉取订单对应的配送日志响应 platformOrderId=【{}】, response=【{}】", platformOrderId, JSONUtil.toJsonStr(recordsResponse));
            return recordsResponse;
        } catch (Exception e) {
            log.error("pullDeliverRecordsAndInsert Error {}", platformOrderId, e);
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 组装配送日志详情时间线实体对象
     *
     * @param platformOrderId
     * @param d
     * @return
     */
    private DeliverRecordTimeline manageDeliverRecordTimeline(String platformOrderId, MtOrderPullDeliverRecordsResponse.DataDTO.TimelineDTO d) {
        DeliverRecordTimeline timeline = new DeliverRecordTimeline();
        timeline.setPlatformOrderId(platformOrderId);
        timeline.setDeliveryId(d.getDeliveryId());
        timeline.setDriverName(d.getDriverName());
        timeline.setDriverPhone(d.getDriverPhone());
        timeline.setRemark(d.getRemark());
        timeline.setState(d.getState());
        timeline.setCreated(d.getCreated());
        timeline.setStateName(d.getStateName());
        timeline.setCreateTime(new Date());
        return timeline;
    }

    /**
     * 组装配送日志主表实体对象
     *
     * @param dto
     * @return
     */
    private DeliverRecord manageDeliverRecord(String platformOrderId, MtOrderPullDeliverRecordsResponse.DataDTO dto) {
        DeliverRecord record = new DeliverRecord();
        record.setPlatformOrderId(platformOrderId);
        record.setDeliveryUuid(dto.getDeliveryUuid());
        record.setStoreId(dto.getStoreId());
        record.setOutId(dto.getOutId());
        record.setDriverName(dto.getDriverName());
        record.setDrivePhone(dto.getDriverPhone());
        record.setDistance(dto.getDistance());
        record.setFee(dto.getFee());
        record.setState(dto.getState());
        record.setWeight(dto.getWeight());
        record.setCreated(dto.getCreated());
        record.setWayCode(dto.getWayCode());
        record.setWayName(dto.getWayName());
        record.setStateLabel(dto.getStateLabel());
        record.setCreateTime(new Date());
        return record;
    }

    /**
     * 组装订单详情实体对象
     *
     * @param d
     * @return
     */
    private MeiTuanOrderDetail manageMeiTuanOrderDetail(MtOrderPullResponse.OrderItemDTO d) {
        MeiTuanOrderDetail detail = new MeiTuanOrderDetail();
        detail.setName(d.getName());
        detail.setSpuId(d.getSpuId());
        detail.setSkuId(d.getSkuId());
        detail.setPlatformSpuId(d.getPlatformSpuId());
        detail.setPlatformSkuId(d.getPlatformSkuId());
        detail.setUpc(d.getUpc());
        detail.setNum(d.getNum());
        detail.setActualPrice(d.getActualPrice());
        detail.setOriginPrice(d.getOriginPrice());
        detail.setCreateTime(new Date());
        return detail;
    }

    /**
     * 组装订单主单实体对象
     *
     * @param m
     * @return
     */
    private MeiTuanOrder manageMeiTuanOrder(MtOrderPullResponse.OrderDTO m) {
        String platformOrderId = m.getPlatformOrderId();
        MeiTuanOrder o = new MeiTuanOrder();
        o.setOrderId(m.getId());
        o.setStoreId(m.getStoreId());
        Shop shopByStoreId = shopService.getShopByStoreId(m.getStoreId());
        Integer shopId = shopByStoreId != null ? shopByStoreId.getId() : null;
        o.setShopId(shopId);
        o.setPlatformOrderId(platformOrderId);
        // 取货码截取平台订单号尾四位
        o.setOrderCode(platformOrderId.substring(platformOrderId.length() - 4));
        o.setPlatformDayId(m.getPlatformDayId());
        o.setOrderWeight(m.getOrderWeight());
        o.setRemark(m.getRemark());
        o.setOrderTime(DateUtil.parse(m.getOrderTime()));
        o.setOrderAmount(m.getOrderAmount());
        o.setOrderOriginalAmount(m.getOrderOriginalAmount());
        o.setOrderReceivableAmount(m.getOrderReceivableAmount());
        o.setExpectTime(DateUtil.parse(m.getExpectTime()));
        o.setPickUp(m.getPickUp());
        o.setTaxerId(m.getTaxerId());
        o.setInvoice(m.getInvoice());
        o.setInvoiceAmount(m.getInvoiceAmount());
        o.setOrderStatus(m.getOrderStatus());
        o.setDeliverStatus(m.getDeliverStatus());
        o.setDeliverType(m.getDeliverType());
        o.setDeliverTypeDesc(m.getDeliverTypeDesc());
        o.setPlatform(m.getPlatform());
        o.setPlatformName(m.getPlatformName());
        o.setOrderDesc(m.getOrderDesc());
        o.setCreateTime(new Date());
        o.setDealTime(null);
        o.setDealFlag(0);
        o.setBrushFlag(0);
        return o;
    }


    /**
     * 模拟订单数据
     *
     * @return
     */
    public MtOrderPullResponse parsePullOrderResponse2Json() {
        try {
            File file = new File("J:\\loveShop\\src\\main\\java\\com\\sky\\loveshop\\entity\\meiTuan\\MtOrderResponse.json");
            MtOrderPullResponse mtOrderPullResponse = new ObjectMapper().readValue(file, MtOrderPullResponse.class);
            return mtOrderPullResponse;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 模拟配送日志数据
     *
     * @return
     */
    private MtOrderPullDeliverRecordsResponse parsePullDeliverRecordResponse2Json() {
        try {
            File file = new File("J:\\loveShop\\src\\main\\java\\com\\sky\\loveshop\\entity\\meiTuan\\MtOrderPullDeliverRecordsResponse.json");
            MtOrderPullDeliverRecordsResponse response = new ObjectMapper().readValue(file, MtOrderPullDeliverRecordsResponse.class);
            return response;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public List<MtOrder> getMtOrderList(MtOrderInfoQO qo) {

        // 查询订单状态为2已接单，且核销标识为0未核销的订单
        Example example = new Example(MeiTuanOrder.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("orderStatus", 2);
        criteria.andEqualTo("dealFlag", 0);
        criteria.andEqualTo("brushFlag", 0);
        criteria.andEqualTo("shopId", qo.getShopId());

        example.setOrderByClause("create_time DESC");
        List<MeiTuanOrder> meiTuanMeiTuanOrders = meiTuanOrderMapper.selectByExample(example);
        List<MtOrder> mtOrders = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(meiTuanMeiTuanOrders)) {
            meiTuanMeiTuanOrders.stream().forEach(mto -> {
                MtOrder mtOrder = new MtOrder();
                BeanUtils.copyProperties(mto, mtOrder);
                mtOrders.add(mtOrder);
            });
        }
        return mtOrders;
    }

    @Override
    public PageInfo<MeiTuanOrder> listMtOrderPages(MtOrderInfoQO qo) {
        PageHelper.startPage(qo.getPageNum(), qo.getPageSize());
        // 查询订单状态为2已接单，且核销标识为0未核销的订单
        Example example = new Example(MeiTuanOrder.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("orderStatus", 2);
        criteria.andEqualTo("dealFlag", 0);
        criteria.andEqualTo("brushFlag", 0);
        criteria.andEqualTo("shopId", qo.getShopId());

        example.setOrderByClause("create_time DESC");
        List<MeiTuanOrder> meiTuanMeiTuanOrders = meiTuanOrderMapper.selectByExample(example);
        return new PageInfo<>(meiTuanMeiTuanOrders);
    }

    @Override
    public PageInfo<MeiTuanOrderVO> listAllMtOrderPages(MtOrderInfoQO qo) {
        if (qo.getShopId() != null) {
            Integer storeId = shopService.getShopById(qo.getShopId()).getStoreId();
            if (storeId == null) {
                return new PageInfo<>();
            }
            qo.setStoreId(storeId);
        }
        PageHelper.startPage(qo.getPageNum(), qo.getPageSize());
        List<MeiTuanOrderVO> mtOrderList = meiTuanOrderMapper.searchAll(qo);

        // 查询出配送人信息 只需要查配送日志的主表即可获取到配送人信息
        if (CollectionUtils.isEmpty(mtOrderList)) {
            return PageInfo.of(new ArrayList<>());
        }

        // 配送人信息
        List<String> platformOrderIdList = mtOrderList.stream().map(MeiTuanOrder::getPlatformOrderId).collect(Collectors.toList());
        List<DeliverRecord> deliverRecordList = deliverRecordsService.getListByPlatformOrderIds(platformOrderIdList);
        Map<String, DeliverRecord> platformOrderId2RecordMap = null;
        if (!CollectionUtils.isEmpty(deliverRecordList)) {
            platformOrderId2RecordMap = deliverRecordList.stream().collect(Collectors.toMap(DeliverRecord::getPlatformOrderId, Function.identity()));
        }

        // 商店信息
        List<Integer> shopIds = mtOrderList.stream().map(MeiTuanOrder::getShopId).collect(Collectors.toList());
        List<Shop> shopsByIds = shopService.getShopsByIds(shopIds);
        Map<Integer, Shop> id2ShopInfoMap = new HashMap<>();
        if (CollectionUtil.isNotEmpty(shopsByIds)) {
            id2ShopInfoMap = shopsByIds.stream().collect(Collectors.toMap(Shop::getId, Function.identity()));
        }

        Map<String, DeliverRecord> finalPlatformOrderId2RecordMap = platformOrderId2RecordMap;
        Map<Integer, Shop> finalId2ShopInfoMap = id2ShopInfoMap;
        mtOrderList.stream().forEach(m -> {
            if (CollectionUtil.isNotEmpty(finalPlatformOrderId2RecordMap)) {
                DeliverRecord deliverRecord = finalPlatformOrderId2RecordMap.get(m.getPlatformOrderId());
                if (null != deliverRecord) {
                    m.setDriverName(deliverRecord.getDriverName());
                    m.setDrivePhone(deliverRecord.getDrivePhone());
                }
            }
            if (CollectionUtil.isNotEmpty(finalId2ShopInfoMap)) {
                Shop shop = finalId2ShopInfoMap.get(m.getShopId());
                if (null != shop) {
                    m.setShopName(shop.getName());
                }
            }
        });
        return new PageInfo<>(mtOrderList);
    }

    @Override
    public Integer dealMtOrder(Integer id) {
        // 美团主订单更改核销标识
        meiTuanOrderMapper.dealMtOrder(id);
        // 扣减库存
        reduceStock(id);
        return 1;
    }

    /**
     * 扣减库存
     *
     * @param id
     */
    private void reduceStock(Integer id) {
        MeiTuanOrder meiTuanOrder = meiTuanOrderMapper.selectByPrimaryKey(id);
        Integer storeId = meiTuanOrder.getStoreId();
        List<MtOrderDetail> mtOrderDetailList = getMtOrderDetailsById(id);
        // (upc:数量)map
        Map<String, Integer> upc2NumMap = mtOrderDetailList.stream().collect(Collectors.toMap(MtOrderDetail::getUpc, MtOrderDetail::getNum));
        List<String> upcList = mtOrderDetailList.stream().map(MtOrderDetail::getUpc).collect(Collectors.toList());
        // 通过upc查到商品id
        List<ProductVO> productVOList = productService.getProductsByUpcList(upcList);
        if (CollectionUtil.isEmpty(productVOList)) {
            log.error("reduceStock error 通过upc没找到对应的商品", id);
            return;
        }
        // (upcCode:productId) map
        Map<String, Integer> upcCode2ProductIdMap = productVOList.stream().collect(Collectors.toMap(Product::getUpcCode, Product::getId));
        List<Integer> productIdList = productVOList.stream().map(Product::getId).collect(Collectors.toList());
        // 通过商品id和商店id找到skuId
        Integer shopId = shopService.getShopByStoreId(storeId).getId();
        List<Sku> skuList = skuService.getSkuListByShoIdAndSkuId(shopId, productIdList);
        if (CollectionUtil.isEmpty(skuList)) {
            log.error("reduceStock error 通过商品id和商店id没找到skuId", id);
            return;
        }
        // (商品id:skuId)map
        Map<Integer, Integer> productId2SkuIdMap = skuList.stream().collect(Collectors.toMap(Sku::getProductId, Sku::getId));
        // 对此skuId对应的商品进行扣减库存
        for (MtOrderDetail d : mtOrderDetailList) {
            String upc = d.getUpc();
            Integer num = upc2NumMap.get(upc);
            Integer productId = upcCode2ProductIdMap.get(upc);
            Integer skuId = productId2SkuIdMap.get(productId);

            StockParam param = new StockParam();
            param.setUserId(9999);
            param.setType(0);
            param.setNum(num);
            param.setSkuId(skuId);
            skuService.changeStockNum(param);
        }
    }

    @Override
    public List<MtOrderDetail> getMtOrderDetailsById(Integer id) {

        MeiTuanOrder meiTuanOrder = meiTuanOrderMapper.selectByPrimaryKey(id);
        String platformOrderId = meiTuanOrder.getPlatformOrderId();
        List<MtOrderDetail> aList = new ArrayList<>();
        // 非"xyzg"开头的订单即美团订单
        if (!platformOrderId.startsWith("xyzg")) {
            Example example = new Example(MeiTuanOrderDetail.class);
            example.createCriteria().andEqualTo("mtOrderId", id);
            List<MeiTuanOrderDetail> detailList = meiTuanOrderDetailMapper.selectByExample(example);

            List<String> supIdList = detailList.stream().map(MeiTuanOrderDetail::getSpuId).distinct().collect(Collectors.toList());
            List<ProductVO> productsByUpcList = productService.getProductsByUpcList(supIdList);

            // 2025-04-26 小姐姐店 存在一个upc_code对应多个商品的情况，条形码不一样，货架号也不一样，这里会报错【Duplicate key 3区606】
            // 针对此种特殊情况，显示货架异常即可，其他商品详情数据不能影响到正常展示
            specialHandleDuplicateKey(productsByUpcList);


            Map<String, String> spuId2ShelfNameMap = new HashMap<>();
            if(CollectionUtil.isNotEmpty(productsByUpcList)) {
                spuId2ShelfNameMap = productsByUpcList.stream().collect(Collectors.toMap(Product::getUpcCode, Product::getShelfName));
            }

            // 通过upc查商品表 product 的 shelf_name字段 作为 no
            List<MtOrderDetail> giftList = new ArrayList<>();
            for (MeiTuanOrderDetail d : detailList) {
                MtOrderDetail mtOrderDetail = new MtOrderDetail();
                //String name = d.getName();
                //String no = name.substring(name.length() - 5, name.length() - 1);
                String no = spuId2ShelfNameMap.get(d.getSpuId());
                // 通过商品详情里面的upc(取spuId作为upc 有些带mtcode开头的) 查商品表 product 的shelf_name字段 作为 no

                BeanUtils.copyProperties(d, mtOrderDetail);
                mtOrderDetail.setNo(no);
                mtOrderDetail.setUpc(d.getSpuId());// 取spuId作为upc 有些带mtcode开头的
                // 组装赠品
                assembleGift(mtOrderDetail, giftList);
                aList.add(mtOrderDetail);
            }
            aList.addAll(giftList);
        } else {
            // "xyzg"开头的订单即私域订单 从我方系统查询私域订单详情数据进行展示
            List<PrivateOrderInfoDetail> detailList = privateOrderInfoService.getPrivateOrderInfoDetailsByOrderNo(platformOrderId);
            if (CollectionUtil.isNotEmpty(detailList)) {
                List<MtOrderDetail> giftList = new ArrayList<>();
                for (PrivateOrderInfoDetail d : detailList) {
                    MtOrderDetail mtOrderDetail = new MtOrderDetail();
                    String name = d.getProductName();
                    //String no = name.substring(name.length() - 5, name.length() - 1);
                    String no = d.getShelfNo();
                    BeanUtils.copyProperties(d, mtOrderDetail);
                    mtOrderDetail.setName(name);
                    mtOrderDetail.setMtOrderId(0);// 保证前端有值
                    mtOrderDetail.setActualPrice(0.0);// 保证前端有值
                    mtOrderDetail.setOriginPrice(0.0);// 保证前端有值
                    mtOrderDetail.setNo(no);
                    mtOrderDetail.setUpc(d.getUpc());
                    // 组装赠品
                    //assembleGift(mtOrderDetail, giftList);
                    aList.add(mtOrderDetail);
                }
                aList.addAll(giftList);
            }
        }
        return aList;
    }

    /**
     * 特殊处理upcCode重复的情况
     * @param productsByUpcList 通过upc查到的商品列表
     */
    private void specialHandleDuplicateKey(List<ProductVO> productsByUpcList) {
        if (CollectionUtil.isEmpty(productsByUpcList)) {
            log.info("specialHandleDuplicateKey productsByUpcList is empty");
            return;
        }
        List<String> collect = productsByUpcList.stream().map(Product::getUpcCode).collect(Collectors.toList());
        // 如果存在upcCode重复的情况
        if (collect.size() != new HashSet<>(collect).size()) {
            log.info("specialHandleDuplicateKey 存在upcCode重复的情况");
            log.info("specialHandleDuplicateKeyBefore 处理前 productsByUpcList = {}", JSONUtil.toJsonStr(productsByUpcList));
            // 按照upcCode分组
            Map<String, List<ProductVO>> upcCode2ProductListMap = productsByUpcList.stream().collect(Collectors.groupingBy(Product::getUpcCode));
            // 遍历upcCode分组
            for (Map.Entry<String, List<ProductVO>> entry : upcCode2ProductListMap.entrySet()) {
                List<ProductVO> productVOList = entry.getValue();
                if (productVOList.size() > 1) {
                    String shelfName = "异常货架号:";
                    for (int i = 0; i < productVOList.size(); i++) {
                        ProductVO productVO = productVOList.get(i);
                        shelfName += productVO.getShelfName() + ",";
                        if (i > 0) {
                            //重复的数据里面除了第一个upcCode正常显示，其他的upcCode加上(productVOList.size() + 1)，防止重复
                            productVO.setUpcCode(productVO.getUpcCode() + (i + 1));
                        }
                    }
                    for (ProductVO productVO : productVOList) {
                        productVO.setShelfName(shelfName);
                    }
                }
            }
        }
        log.info("specialHandleDuplicateKeyBefore 处理后 productsByUpcList = {}", JSONUtil.toJsonStr(productsByUpcList));
    }

    /**
     * 组装赠品
     */
    private void assembleGift(MtOrderDetail mtOrderDetail, List<MtOrderDetail> giftList) {
        // 根据订单内的upc找到商品product
        // 通过商品product和美团商店storeId找到sku
        // 再通过sku找到此sku是否配置赠品sku，如果配置了则将赠品也当做一个商品项展示到待核销详情项目内，且将赠品价格改为0
        ProductVO product = null;
        try {
            product = productService.getProductByUpc(mtOrderDetail.getUpc());
            if (product == null) {
                return;
            }
            SkuVO sku = skuService.getShelfIdByProductIdAndShopId(product.getId(), mtOrderDetail.getShopId());
            if (sku.getGiftId() == null) {
                return;
            }
            SkuVO giftSku = skuService.getSkuById(sku.getGiftId());

            MtOrderDetail giftOrderDetail = new MtOrderDetail();
            giftOrderDetail.setId(null);
            giftOrderDetail.setMtOrderId(mtOrderDetail.getMtOrderId());
            giftOrderDetail.setName("【赠品】" + giftSku.getProductName());
            giftOrderDetail.setNo(giftSku.getPlace());
            giftOrderDetail.setUpc(giftSku.getUpc());
            giftOrderDetail.setNum(1);
            // 实付价格置为0元
            giftOrderDetail.setActualPrice(0.0);
            giftOrderDetail.setOriginPrice(giftSku.getSalesPrice().doubleValue());
            giftOrderDetail.setCreateTime(new Date());
            giftOrderDetail.setStoreId(mtOrderDetail.getStoreId());
            giftOrderDetail.setShopId(giftSku.getShopId());

            giftList.add(giftOrderDetail);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("assembleGiftError upc={} productId={} mtOrderId={}", mtOrderDetail.getUpc(), (product!=null ? product.getId(): null), mtOrderDetail.getMtOrderId(), e);
        }
    }

    @Override
    public SkuVO getSkuDetailByBarCode(String barCode, Integer shopId) throws BizException {
        log.info("getSkuDetailByBarCode 入参barCode={} shopId={}", barCode, shopId);
        ProductVO productVO = productService.getProductByBarCode(barCode, shopId);

        SkuVO skuVO = skuService.getSkuByProductAndShopId(productVO.getId(), shopId);
        if (skuVO == null) {
            log.error("getSkuDetailByBarCode 通过条形码和商店id获取不到sku barCode={},shopId={}", barCode, shopId);
            throw new BizException(BizExceptionEnum.PRODUCT_NOT_EXIST_BY_BAR_CODE);
        }
        skuVO.setPicture(productVO.getPicture());
        skuVO.setUpc(productVO.getUpcCode());
        return skuVO;
    }

    @Override
    public MeiTuanOrder getMeiTuanOrderByOrderCode(String orderCode, Integer storeId) {
        MeiTuanOrder meiTuanOrder = meiTuanOrderMapper.getMeiTuanOrderByOrderCode(orderCode, storeId);
        return meiTuanOrder;
    }

    @Override
    public MeiTuanOrder getMeiTuanOrderByPhoneCode(String phoneCode, Integer storeId) {
        MeiTuanOrder meiTuanOrder = meiTuanOrderMapper.getMeiTuanOrderByPhoneCode(phoneCode, storeId);
        return meiTuanOrder;
    }

    @Override
    public Integer markBrushFlag(Integer id) {
        return meiTuanOrderMapper.markBrushFlag(id);
    }
}
